package com.clp.protocol.core.utils.time;

import com.clp.protocol.core.utils.ByteUtil;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {

    private static final SimpleDateFormat REALTIME_DATE_FORMAT = new SimpleDateFormat(DateFormatter.FORMATTER_1.getExpr());


    /**
     * 将一个7字节的时标数组转为Date类型的日期
     *
     * @param bytes7
     * @return
     */
    public static Date CP56Time2aBytes7ToDate(byte[] bytes7) {
        int year = (bytes7[6] & 0x7F) + 2000;
        int month = bytes7[5] & 0x0F;
        int day = bytes7[4] & 0x1F;
        int hour = bytes7[3] & 0x1F;
        int minute = bytes7[2] & 0x3F;
        int second = bytes7[1] > 0 ? bytes7[1] : (int) (bytes7[1] & 0xff);
        int millisecond = bytes7[0] > 0 ? bytes7[0] : (int) (bytes7[0] & 0xff);
        millisecond = (second << 8) + millisecond;
        second = millisecond / 1000;
        millisecond = millisecond % 1000;
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DAY_OF_MONTH, day);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.MILLISECOND, millisecond);
        return calendar.getTime();
    }

    /**
     * 将一个Date类型的日期转换成一个7字节的字节数组
     *
     * @param date
     * @return
     */
    public static byte[] dateToCP56Time2aBytes7(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR) - 2000;
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        int millSecond = calendar.get(Calendar.MILLISECOND);

        byte[] bytes = new byte[7];
        int millSeconds = second * 1000 + millSecond;
        byte[] millSecondsBytes = ByteUtil.intToBytes2LE(millSeconds);
        bytes[0] = millSecondsBytes[0]; // 填入毫秒数
        bytes[1] = millSecondsBytes[1];
        bytes[2] = (byte) minute; // 填入分钟
        bytes[3] = (byte) hour; // 填入秒
        int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
        if (calendar.getFirstDayOfWeek() == Calendar.SUNDAY) {
            weekDay -= 1;
            if (weekDay == 0) weekDay = 7;
        }
        bytes[4] = 0;
        bytes[4] |= (byte) weekDay;
        bytes[4] <<= 5; // 填入星期
        bytes[4] |= (byte) day; // 填入日
        bytes[5] = (byte) month; // 填入月
        bytes[6] = (byte) year; // 填入年

        return bytes;
    }

    public static Instant stringToInstant(String str) {
        if (str == null) {
            return null;
        }
        return Instant.parse(str);
    }

    /**
     * 获取时间
     * @return
     */
    public static Instant getNowInstant() {
        return  Instant.now();
    }

    public static Date getNowDate() {
        return new Date();
    }

    public static Date getZeroDate() {
        return new Date(0);
    }

    public static Instant dateToInstant(Date date) {
        if (date == null) {
            return getNowInstant();
        }
        return date.toInstant();
    }

    public static Date instantToDate(Instant instant) {
        return Date.from(instant);
    }

    public static String dateToString(Date timestamp) {
        synchronized (REALTIME_DATE_FORMAT) {
            return REALTIME_DATE_FORMAT.format(timestamp);
        }
    }




    /**
     * 按照指定格式将date类型产生一个日期字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String dateToFormatString(Date date, String format) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        String dateFormatStr = simpleDateFormat.format(date);
        return dateFormatStr;
    }

    private static Date stringToDate(String str, boolean zero) {
        synchronized (REALTIME_DATE_FORMAT) {
            try {
                return REALTIME_DATE_FORMAT.parse(str);
            } catch (Exception e) {
                return zero ? new Date(0) : new Date();
            }
        }
    }

    /**
     * 时间格式转换
     *
     * @param str 时间字符串
     * @return date对象
     */
    public static Date stringToDateDefaultZero(String str) {
        return stringToDate(str, true);
    }

    public static Date stringToDateDefaultNow(String str) {
        return stringToDate(str, false);
    }
}
